iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
0
自我挑戰組

React 30 天學習歷程系列 第 15

【Day 15】個人網站實作(二):react-router-dom 使用

  • 分享至 

  • xImage
  •  

前一篇有提到如何安裝 react-router-dom,這一篇我們會透過實作來運用這個套件裡面的一些元件及功能。

Link 元件

header 的部分因為會做到 link 連結,所以我們可以使用 react-router-dom 裡面的 Link 元件來做頁面路由跳轉功能。在使用 Link 元件前,我們必須先在 index.js 中去引用 Router 元件,不然頁面會報錯,如下:

上面這個錯誤是指我們不能在 Router 元件外面使用 Link,必須在元件裡面使用,或是用 Router 元件包住頂層元件(App),如下面在 src 資料夾中的 index.js 裡面引入Router 元件,再進行包覆

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './pages/App';
import * as serviceWorker from './serviceWorker';
//引入 Router
import { BrowserRouter as Router} from 'react-router-dom';

ReactDOM.render(
    // 用 `Router` 元件包住`App`
  <React.StrictMode>
    <Router><App /></Router>
  </React.StrictMode>,
  document.getElementById('root')
);

Link 元件使用方式很簡單,是直接用 Link 去包住連接的元素

import React from 'react';
import logo from './logo.svg';
import styles from './App.module.scss';
import { Link } from 'react-router-dom';
import HomePage from './HomePage/HomePage'; //首頁
import WorkPage from './WorkPage/WorkPage'; //作品列表頁
import WorkDetailPage from './WorkDetailPage/WorkDetailPage'; //作品詳情頁

function App() {
  return (
    <div className={styles.App}>
      <header className={styles.header}>
        <Link to="/">
          <div className={styles.siteName}>
            Leo's Website
          </div>
        </Link>
        <div className={styles.menu}>
          <Link to="/"><span>Home</span></Link>
          <Link to="/works"><span>Works</span></Link>
        </div>
      </header>
      <section className={styles.content}>
        Content
      </section>
      <footer className={styles.footer}>
      <div className={styles.copyright}>Copyright © 2020 LeoLiu All rights reserved.</div>
      </footer>
    </div>
  );
}

export default App;

利用 Route 元件添加路由

接下來我們可以利用 Route 來增加路由,讓 Link 改變路徑的時候能夠順利連結到其他頁面,Route 中有幾個屬性,分別是路由對應的路徑 path,和對應的元件 component,另外還有一個 exact 是當路由和 component 有對應才會顯示。如下:

<Route path="/" exact component={} />

我們可以先在 App.js 中新增路由,如下:

import React from 'react';
import logo from './logo.svg';
import styles from './App.module.scss';
import { Link, Route } from 'react-router-dom';
import HomePage from './HomePage/HomePage'; //首頁
import WorkPage from './WorkPage/WorkPage'; //作品列表頁
import WorkDetailPage from './WorkDetailPage/WorkDetailPage'; //作品詳情頁

function App() {
  return (
    <div className={styles.App}>
      <header className={styles.header}>
        <Link to="/">
          <div className={styles.siteName}>
            Leo's Website
          </div>
        </Link>
        <div className={styles.menu}>
          <Link to="/"><span>Home</span></Link>
          <Link to="/works"><span>Works</span></Link>
        </div>
      </header>
      <section className={styles.content}>
        <Route path="/" exact component={ HomePage } />
        <Route path="/works" exact component={ WorkPage} />
        <Route path="/works/:id" exact component={ WorkDetailPage} />
      </section>
      <footer className={styles.footer}>
      <div className={styles.copyright}>Copyright © 2020 LeoLiu All rights reserved.</div>
      </footer>
    </div>
  );
}

export default App;

接著再製作對應的 component,分別是 HomePage(首頁)、WorkPage(作品列表頁)、WorkDetailPage(作品詳情頁),這邊放上 HomePage 程式碼範例:

import React from 'react';

const HomePage = () => {
    return <div>
        HomePage
    </div>    
}

export default HomePage;

完成對應頁面的 component 後,我們就可以利用連結來切換頁面囉(這邊因為文章編輯器似乎無法支援顯示 Route 元件,所以程式碼全部變成了白色,但是功能上是沒問題的)。

利用 withRouter 獲取當前路由

react-router-dom 有一個元件能取得當前的路由,叫做 withRouter,我們可以利用它包住一個元件,這樣當我們調用 withRouter 時就會返回一個全新的元件,如下

import logo from './logo.svg';
import styles from './App.module.scss';
// 調用 withRouter
import { Link, Route, withRouter } from 'react-router-dom';
import HomePage from './HomePage/HomePage';
import WorkPage from './WorkPage/WorkPage';
import WorkDetailPage from './WorkDetailPage/WorkDetailPage';

const App = (props) => {
  const { location } = props;
  return (
    //...
  );
}

// 利用 withRouter 包住 App 元件
export default withRouter(App);

withRouter 擁有 react-router 的一些屬性,我們可以透過 props 解構賦值取得一個叫做 location 的屬性,這是 react-router 本身的屬性,如果 console 它,就可以看到以下這些屬性,其中的 pathname 就是當前路由名稱

透過取得路由名稱,我們就可以執行不少事情,這邊我們利用路由名稱來給連結添加樣式,這樣當連結在對應的頁面時,就會讓連結看起來比較醒目,改善使用者體驗。

import React from 'react';
import logo from './logo.svg';
import styles from './App.module.scss';
import { Link, Route, withRouter } from 'react-router-dom';
import HomePage from './HomePage/HomePage'
import WorkPage from './WorkPage/WorkPage'
import WorkDetailPage from './WorkDetailPage/WorkDetailPage'

const App = (props) => {
  const { location } = props;
  return (
    <div className={styles.App}>
      <header className={styles.header}>
        <Link to="/">
          <div className={styles.siteName}>
            Leo's Website
          </div>
        </Link>
        <div className={styles.menu}>
          <Link to="/"><span className={ location.pathname === '/' ? styles.active : ''}>Home</span></Link>
          <Link to="/works"><span className={ location.pathname === '/works' ? styles.active : ''}>Works</span></Link>
        </div>
      </header>
      <section className={styles.content}>
        <Route path="/" exact component={ HomePage } />
        <Route path="/works" exact component={ WorkPage} />
        <Route path="/works/:id" exact component={ WorkDetailPage} />
      </section>
      <footer className={styles.footer}>
      <div className={styles.copyright}>Copyright © 2020 LeoLiu All rights reserved.</div>
      </footer>
    </div>
  );
}

export default withRouter(App);

小結

這一篇透過實作來運用一些 react-router-dom 的元件,讓我們更方便的操作路由,下一篇會將整個網站大致完成。


上一篇
【Day 14】個人網站實作(一):create-react-app + 套件安裝及版面布置
下一篇
【Day 16】個人網站實作(三)
系列文
React 30 天學習歷程30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言